Imports System.Collections

Public Class OrderStatusUpdate
    Inherits System.Web.UI.Page

    Private Const ORDER_UPDATE_PAGEBO_SESSION_NAME As String = "MIMS_WRS.Web.OrderStatusUpdate.PageBO"
    Private Const ORDER_UPDATE_PAGEBO_LASTWEEK_SESSION_NAME As String = "MIMS_WRS.Web.OrderStatusUpdate.PageBOLastweek"
    Private Const ORDER_LIST_URL As String = "/Customer/CustomerList.aspx"

    Protected WithEvents lblWeek As System.Web.UI.WebControls.Label
    Protected WithEvents lblYear As System.Web.UI.WebControls.Label
    Protected WithEvents PlaceHolder1 As System.Web.UI.WebControls.PlaceHolder
    Protected WithEvents btnLoad As System.Web.UI.WebControls.Button
    Protected WithEvents btnSaveAndCont As System.Web.UI.WebControls.Button
    Protected WithEvents Header1 As Header
    Private _isValidData As Boolean = True



#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub
    Protected WithEvents btnReset As System.Web.UI.WebControls.Button
    Protected WithEvents btnSave As System.Web.UI.WebControls.Button
    Protected WithEvents btnCancel As System.Web.UI.WebControls.Button
    Protected WithEvents lblCustomerName As System.Web.UI.WebControls.Label

    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

#Region "   Properties"
    Protected Property PageBOList() As Collection
        Get
            If IsNothing(Session(ORDER_UPDATE_PAGEBO_SESSION_NAME)) Then
                Throw New ApplicationException("Session expried. Please re-login")
            End If
            Return CType(Session(Me.ORDER_UPDATE_PAGEBO_SESSION_NAME), Collection)
        End Get
        Set(ByVal Value As Collection)
            Session(Me.ORDER_UPDATE_PAGEBO_SESSION_NAME) = Value
        End Set
    End Property

    Protected Property PageBOLastweekList() As Collection
        Get
            If IsNothing(Session(ORDER_UPDATE_PAGEBO_LASTWEEK_SESSION_NAME)) Then
                Throw New ApplicationException("Session expried. Please re-login")
            End If
            Return CType(Session(Me.ORDER_UPDATE_PAGEBO_LASTWEEK_SESSION_NAME), Collection)
        End Get
        Set(ByVal Value As Collection)
            Session(Me.ORDER_UPDATE_PAGEBO_LASTWEEK_SESSION_NAME) = Value
        End Set
    End Property

    Private Property Url() As String
        Get
            Return CStr(ViewState("Url"))
        End Get
        Set(ByVal Value As String)
            ViewState("Url") = Value
        End Set
    End Property

    'Private Property UrlReferrer() As String
    '    Get
    '        Return CStr(ViewState("UrlReferrer"))
    '    End Get
    '    Set(ByVal Value As String)
    '        ViewState("UrlReferrer") = Value
    '    End Set
    'End Property

    Private ReadOnly Property ReturnURL() As String
        Get
            If IsNothing(Request.QueryString("ru")) Then
                Return AppRoot() & Me.ORDER_LIST_URL
            End If
            Return Server.UrlDecode(Request.QueryString("ru"))
        End Get
    End Property

    Protected ReadOnly Property CustomerID() As Integer
        Get
            Try
                If IsNothing(Request.QueryString("id")) Then
                    Throw New Exception
                End If

                Dim id As Integer
                id = CInt(Request.QueryString("id"))

                If Not id > 0 Then
                    Throw New Exception
                End If

                Return id
            Catch ex As Exception
                Throw New ApplicationException("Invalid or missing parameter", ex)
            End Try
        End Get
    End Property

    Protected Property ControlsName() As String
        Get
            Try
                Return CStr(ViewState("ControlsName"))
            Catch ex As Exception
                Return ""
            End Try
        End Get
        Set(ByVal Value As String)
            ViewState("ControlsName") = Value
        End Set
    End Property

    Private Property IsValidData() As Boolean
        Get
            Return Me._isValidData
        End Get
        Set(ByVal Value As Boolean)
            Me._isValidData = Value
        End Set
    End Property

#End Region

#Region "   Private member"
    Private Sub AddControls()
        Dim i As Integer
        Dim ctrlsName As String = ""
        Dim osh As OrderStatusUpdateHeaderCtrl = CType(LoadControl("../Controls/OrderStatusUpdateHeaderCtrl.ascx"), OrderStatusUpdateHeaderCtrl)
        Dim osf As OrderStatusUpdateFooterCtrl = CType(LoadControl("../Controls/OrderStatusUpdateFooterCtrl.ascx"), OrderStatusUpdateFooterCtrl)
        PlaceHolder1.Controls.Add(osh)
        For i = 1 To Me.PageBOList.Count
            Dim os As OrderStatusUpdateCtrl = CType(LoadControl("../Controls/OrderStatusUpdateCtrl.ascx"), OrderStatusUpdateCtrl)
            os.FillData(CType(Me.PageBOLastweekList(i), COrderStatus), CType(Me.PageBOList(i), COrderStatus))
            PlaceHolder1.Controls.Add(os)
            ctrlsName += PlaceHolder1.Controls(i).ClientID
            ctrlsName += ","
        Next
        PlaceHolder1.Controls.Add(osf)
        Me.ControlsName = ctrlsName
    End Sub

    Private Sub Save()

        Dim i As Integer = 1
        Dim obj As COrderStatus

        'First of all, we update all the OrderStatus instances. 
        For Each obj In Me.PageBOList
            Dim os As OrderStatusUpdateCtrl
            os = CType(PlaceHolder1.Controls(i), OrderStatusUpdateCtrl)
            os.UpdateData(obj)
            'obj.Save()
            i += 1
        Next

        'Then we also need to check the unique requirement of the InvoiceNo
        'before saving OrderStatus objects.
        ValidateInputDataAndSave()

    End Sub

    Private Sub ValidateInputDataAndSave()
        Dim i As Integer = 1
        Dim obj As COrderStatus

        For Each obj In Me.PageBOList
            'Validate unique InvoiceNO.
            Dim isUnique As Boolean
            isUnique = ValidateUniqueInvoiceNo(obj, i)

            'In the case that the validation fails, we will display the error msg.
            Dim os As OrderStatusUpdateCtrl
            os = CType(PlaceHolder1.Controls(i), OrderStatusUpdateCtrl)
            os.ValidateUniqueInvoiceNo(isUnique)

            'Save the OrderStatus instance when it's InvoiceNo is unique.
            If (isUnique) Then
                obj.Save()
            Else
                Me.IsValidData = False
            End If

            i += 1
        Next
    End Sub

    Private Function ValidateUniqueInvoiceNo(ByVal orderStatus As COrderStatus, ByVal index As Integer) As Boolean
        If (orderStatus.InvoiceNo Is Nothing OrElse orderStatus.InvoiceNo.Trim().Length = 0) Then
            Return True
        End If

        'Compare this instance with other ones in the list.
        Dim unique As Boolean
        unique = ValidateInvoiceNoInList(orderStatus, index)

        If (unique) Then
            'If OK, continue with other ones in DB.
            unique = ValidateInvoiceNoInDB(orderStatus, index)
        End If

        Return unique
    End Function

    Private Function ValidateInvoiceNoInList(ByVal orderStatus As COrderStatus, ByVal index As Integer) As Boolean
        Dim i As Integer = 1
        Dim obj As COrderStatus

        For Each obj In Me.PageBOList
            If (i <> index) And (obj.InvoiceNo = orderStatus.InvoiceNo) Then
                Return False
            End If

            i += 1
        Next

        Return True
    End Function

    Private Function ValidateInvoiceNoInDB(ByVal orderStatus As COrderStatus, ByVal index As Integer) As Boolean
        'We are going to check to see if the InvoiceNO is unique in the DB
        'except the ones currently in the list.
        Dim osIDs As New ArrayList
        Dim i As Integer = 1
        Dim obj As COrderStatus

        For Each obj In Me.PageBOList
            If (i <> index) And (obj.ID > 0) Then
                osIDs.Add(obj.ID)
            End If
            i += 1
        Next

        Return COrderStatus.ValidateUniqueInvoiceNo(orderStatus.ID, orderStatus.InvoiceNo, osIDs)
    End Function
#End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        If Not Page.IsPostBack Then
            Security.InternalAndAdminOnly()
            Me.Url = Request.Url.PathAndQuery

            Me.Header1.NavigationBar.Add("Back to Customer List", Me.ReturnURL)
            Me.Header1.MenuIndex = EMenuIndex.InternalUserList

            Me.lblCustomerName.Text = CUser.GetName(Me.CustomerID)
            Me.lblWeek.Text = Week(Now).ToString()
            Me.lblYear.Text = Year(Now).ToString()

            Dim dt As DataTable = COrder.GetAllPurchaseOrderActiveForCustomer(Me.CustomerID)
            If dt.Rows.Count < 1 Then
                Me.btnLoad.Enabled = False
            End If

            '== PRE-CONDITION CHECK ==
            '"... is only enabled for all PO (include independent PO) with status is Active... "
            'from uc_SystemOrderListPage
            'If CType(objOrder.OrderType, EOrderType) = EOrderType.Bulk_Order _
            '    Or objOrder.Status <> EOrderStatus.Active Then
            '    Throw New ApplicationException("You can not update status for this order")
            'End If
            '========================

            Dim colOS As New Collection
            Dim colLastOS As New Collection
            Dim row As DataRow
            For Each row In dt.Rows
                Dim obj As New COrderStatus
                Dim objLastOS As New COrderStatus
                Dim id As Integer = Convert.ToInt32(row(0))
                Dim orderDate As Date = CDate(row(1))

                Try
                    ' load production status data of the current year and week                
                    obj.Load(id, Week(Now), Year(Now))
                    obj.OrderDate = orderDate
                Catch ex As DataNotExistsException
                    ' new week
                    obj.Init()
                    obj.OrderID = id
                    obj.OrderDate = orderDate
                Catch ex As Exception
                    Throw New ApplicationException("Failed to load order status data", ex)
                End Try

                Try
                    If (obj.ID > 0) Then
                        objLastOS = obj.LastWeek()
                    Else
                        objLastOS = Nothing
                    End If

                    'Catch ex As DataNotExistsException
                Catch ex As Exception
                    Me.btnLoad.Enabled = False
                    'objLastOS.Init()
                    'objLastOS.OrderID = id
                    'objLastOS.OrderDate = orderDate
                    'Throw New ApplicationException("Failed to load order status data", ex)
                End Try

                colOS.Add(obj)
                colLastOS.Add(objLastOS)
            Next

            Me.PageBOList = colOS
            Me.PageBOLastweekList = colLastOS

            'add attribute

        End If
        AddControls()
    End Sub

#Region "   Button's event handler"
    Private Sub btnReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReset.Click
        Response.Redirect(Me.Url)
    End Sub

    Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
        Save()
        If (Me.IsValidData) Then
            Response.Redirect(Me.ReturnURL)
        End If
    End Sub

    Private Sub btnSaveAndCont_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSaveAndCont.Click
        Save()
    End Sub

    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        Response.Redirect(Me.ReturnURL)
    End Sub

    Private Sub btnLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoad.Click
        ' fill to memory
        Dim obj As COrderStatus
        Dim i, j As Integer
        For i = 1 To Me.PageBOLastweekList.Count
            obj = CType(Me.PageBOLastweekList.Item(i), COrderStatus)
            If (Not (obj Is Nothing)) Then

                With CType(Me.PageBOList.Item(i), COrderStatus)
                    .Cost = obj.Cost
                    .DepartureDate = obj.DepartureDate
                    .DocSent = obj.DocSent
                    .DocSentDate = obj.DocSentDate
                    .EstTimeArrival = obj.EstTimeArrival
                    .PrevEstTimeArrival = obj.PrevEstTimeArrival
                    .EstTimeDelivery = obj.EstTimeDelivery
                    .PrevEstTimeDelivery = obj.PrevEstTimeDelivery
                    .InvoiceDate = obj.InvoiceDate
                    .InvoiceNo = obj.InvoiceNo
                    .InvoiceValue = obj.InvoiceValue
                    .PayReceived = obj.PayReceived
                    .PayReceivedDate = obj.PayReceivedDate
                    .PercentCompleted = obj.PercentCompleted
                    .Vessel = obj.Vessel
                End With
            End If
        Next

        i = 1
        For Each obj In Me.PageBOLastweekList
            Dim os As OrderStatusUpdateCtrl
            os = CType(PlaceHolder1.Controls(i), OrderStatusUpdateCtrl)
            os.FillData(CType(Me.PageBOLastweekList(i), COrderStatus), CType(Me.PageBOList(i), COrderStatus))
            i += 1
        Next

    End Sub

#End Region

End Class
